package br.unifor.mia.graph.util;

public class CalcUtil {
	
	private static double[] arrayIntToDouble(int[] crimesSequence) {
	
		double[] eixoY = new double[crimesSequence.length];
		
		for (int i = 0 ; i < crimesSequence.length ; i++) {
			eixoY[i] = crimesSequence[i];
		}
		return eixoY;
	}

	private static double[] createEixoX(double[] sequence) {
		
		int tamanho = sequence.length;
	
		double[] eixoX = new double[tamanho];
	
		for (int i = 0 ; i < tamanho ; i++) {
			eixoX[i] = i;
		}
		return eixoX;
	}

	// Calcula média aritimetica
	public static double mediaAritmetica(double[] array) {
		return somatorio(array) / array.length;
	}

	// Calcula somatório
	public static double somatorio(double[] array) {

		double somatorio = 0;
		for (double valor : array) {
			somatorio += valor;
		}
		return somatorio;
	}

	public static double calcAlpha(int[] crimesSequence) {
	
		double[] eixoY = arrayIntToDouble(crimesSequence);
	
		return calcAlpha(eixoY);
	}

	public static double calcAlpha(double[] y) {
	
		double[] eixoX = createEixoX(y);
	
		return calcAlpha(eixoX, y);
	}

	// Calcula alpha
	public static double calcAlpha(double x[], double y[]) {
		double alphaNum = 0.0;
		double alphaDen = 0.0;
		int i = 0;

		double mediaX = mediaAritmetica(x);
		double mediaY = mediaAritmetica(y);

		while (i < x.length) {
			alphaNum += (x[i] - mediaX) * (y[i] - mediaY);
			alphaDen += Math.pow((x[i] - mediaX), 2);
			i++;
		}
		if (alphaDen == 0)
			return 0.0;
		else
			return alphaNum / alphaDen;
	}

	public static double calcR2(double alpha, int[] crimesSequence) {

		double[] eixoY = arrayIntToDouble(crimesSequence);

		return calcR2(alpha, eixoY);
	}

	public static double calcR2(double slope, double y[]) {
		return calcR2(slope, createEixoX(y), y);
	}
	
	public static double calcR2(double slope, double x[], double y[]) {
		int i = 0;
		double sx = 0;
		double sy = 0;

		double mediaX = mediaAritmetica(x);
		double mediaY = mediaAritmetica(y);

		while (i < x.length) {
			sx += Math.pow((x[i] - mediaX), 2);
			sy += Math.pow((y[i] - mediaY), 2);
			i++;
		}

		double ssX = Math.sqrt(sx / (x.length - 1));
		double ssY = Math.sqrt(sy / (x.length - 1));

		return (slope * ssX) / ssY;
	}
}
